package com.coai.user.service

import com.coai.common.exception.ConflictException
import com.coai.common.exception.ResourceNotFoundException
import com.coai.user.model.*
import com.coai.user.repository.*
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * 组织服务
 */
@Service
class OrganizationService(
    private val organizationRepository: OrganizationRepository,
    private val userOrganizationRepository: UserOrganizationRepository
) {
    
    /**
     * 创建组织
     */
    @Transactional
    fun createOrganization(
        name: String,
        code: String,
        parentId: String?,
        type: OrgType,
        leaderId: String? = null
    ): Organization {
        
        if (organizationRepository.existsByCode(code)) {
            throw ConflictException("组织代码已存在")
        }
        
        // 计算层级
        val level = if (parentId == null) {
            1
        } else {
            val parent = organizationRepository.findById(parentId)
                .orElseThrow { ResourceNotFoundException("父组织不存在") }
            parent.level + 1
        }
        
        val org = Organization(
            name = name,
            code = code,
            parentId = parentId,
            type = type,
            level = level,
            leaderId = leaderId
        )
        
        return organizationRepository.save(org)
    }
    
    /**
     * 获取组织树
     */
    fun getOrganizationTree(parentId: String? = null): List<OrganizationNode> {
        val orgs = organizationRepository.findByParentIdOrderBySortOrder(parentId)
        
        return orgs.map { org ->
            OrganizationNode(
                id = org.id!!,
                name = org.name,
                code = org.code,
                type = org.type,
                level = org.level,
                leaderId = org.leaderId,
                enabled = org.enabled,
                children = getOrganizationTree(org.id)
            )
        }
    }
    
    /**
     * 添加用户到组织
     */
    @Transactional
    fun addUserToOrganization(
        userId: String,
        organizationId: String,
        isPrimary: Boolean = false,
        position: String? = null
    ) {
        
        if (userOrganizationRepository.existsByUserIdAndOrganizationId(userId, organizationId)) {
            throw ConflictException("用户已在该组织中")
        }
        
        // 如果是主组织，需要取消其他主组织
        if (isPrimary) {
            val currentPrimary = userOrganizationRepository.findByUserIdAndIsPrimary(userId, true)
            currentPrimary?.let {
                val updated = it.copy(isPrimary = false)
                userOrganizationRepository.save(updated)
            }
        }
        
        val userOrg = UserOrganization(
            userId = userId,
            organizationId = organizationId,
            isPrimary = isPrimary,
            position = position
        )
        
        userOrganizationRepository.save(userOrg)
    }
    
    /**
     * 获取用户的组织列表
     */
    fun getUserOrganizations(userId: String): List<OrganizationInfo> {
        val userOrgs = userOrganizationRepository.findByUserId(userId)
        val orgIds = userOrgs.map { it.organizationId }
        val orgs = organizationRepository.findAllById(orgIds)
        
        return userOrgs.map { userOrg ->
            val org = orgs.find { it.id == userOrg.organizationId }!!
            OrganizationInfo(
                id = org.id!!,
                name = org.name,
                code = org.code,
                type = org.type,
                isPrimary = userOrg.isPrimary,
                position = userOrg.position
            )
        }
    }
    
    /**
     * 获取组织成员
     */
    fun getOrganizationMembers(organizationId: String): List<String> {
        return userOrganizationRepository.findByOrganizationId(organizationId)
            .map { it.userId }
    }
}

/**
 * 组织树节点
 */
data class OrganizationNode(
    val id: String,
    val name: String,
    val code: String,
    val type: OrgType,
    val level: Int,
    val leaderId: String?,
    val enabled: Boolean,
    val children: List<OrganizationNode>
)

/**
 * 组织信息
 */
data class OrganizationInfo(
    val id: String,
    val name: String,
    val code: String,
    val type: OrgType,
    val isPrimary: Boolean,
    val position: String?
)
